import numpy as np


def MA_Sorter(df_day, day_list, key="close", method="sort", mode="UP"):  # mode = G or L
    """
    + df = pd.DataFrame pandas表格
    + day_list = wave 波浪
    + key = close, open, low, high 主要信息
    + methord= sort/count def: sort
    + mode = UP/DOWN def G
    :: return num
    ```python
    a = 0
    counts = 1
    if method == "sort":
        for num in range(len(day_list) - 1):
            col1 = "{}_ma_{}".format(key, day_list[num])
            col2 = "{}_ma_{}".format(key, day_list[num + 1])

            if mode == "UP" and df_day[col1] > df_day[col2]:
                a += 1
            elif mode == "DOWN" and df_day[col1] < df_day[col2]:
                a += -1
            else:
                break
    elif method == "count":
        counts += 1
        for num in range(len(day_list) - 1):
            col1 = "{}_ma_{}".format(key, day_list[num])
            col2 = "{}_ma_{}".format(key, day_list[num + 1])
            if df_day[col2] != (0 or np.nan):
                if df_day[col1] < df_day[col2]:
                    a += 1
                elif df_day[col1] > df_day[col2]:
                    a += -1
    return a / counts
    ```
    """
    a = 0
    counts = 1
    if method == "sort":
        for num in range(len(day_list) - 1):
            col1 = "{}_ma_{}".format(key, day_list[num])
            col2 = "{}_ma_{}".format(key, day_list[num + 1])

            if mode == "UP" and df_day[col1] > df_day[col2]:
                a += 1
            elif mode == "DOWN" and df_day[col1] < df_day[col2]:
                a += -1
            else:
                break
    elif method == "count":
        counts += 1
        for num in range(len(day_list) - 1):
            col1 = "{}_ma_{}".format(key, day_list[num])
            col2 = "{}_ma_{}".format(key, day_list[num + 1])
            if df_day[col2] != (0 or np.nan):
                if df_day[col1] < df_day[col2]:
                    a += 1
                elif df_day[col1] > df_day[col2]:
                    a += -1
    return a / counts


def NotZero(df_day, day_list, key="close"):
    """
    + df_day, day_list, key="close"
    ```python
    lists = []
    for num in day_list:
        col = "{}_ma_{}".format(key, day_list[num])
        if df_day[col] != 0:
            lists.append(col)
        else:
            return lists
    ```
    """
    lists = []
    for num in day_list:
        col = "{}_ma_{}".format(key, day_list[num])
        if df_day[col] != 0:
            lists.append(col)
        else:
            return lists


def Ma_Compare(df_day, day_list, key="close"):
    """
    + df_day, day_list, key="close"
    :: return: Ture / False
    ```python
    col1 = "{}_ma_{}".format(key, day_list[0])
    com_dic = {5: 0.01, 13: 0.02, 21: 0.04, 55: 0.055, 89: 0.065}
    for num in com_dic:
        col2 = "{}_ma_{}".format(key, num)
        a = df_day[col2]
        if a != 0:
            ret = a / df_day[col1]
            if ret >= com_dic[num]:
                pass
            else:
                return False
        else:
            continue
    return True
    ```
    """
    col1 = "{}_ma_{}".format(key, day_list[0])
    com_dic = {5: 0.01, 13: 0.02, 21: 0.04, 55: 0.055, 89: 0.065}

    for num in com_dic:
        col2 = "{}_ma_{}".format(key, num)
        a = df_day[col2]
        if a != 0:
            ret = a / df_day[col1]
            if ret >= com_dic[num]:
                pass
            else:
                return False
        else:
            continue
    return True


def MA_LastNoneZero(df_day, day_list, key="close"):
    """
    MA_LastNoneZero(df,  day_list, day, key='close')
    + df_day, day_list, key="close"
    :: return [num, res, col]
    ```python
    l = day_list.copy()
    l.reverse()
    # print(l)
    for num in l:
        col = "{}_ma_{}".format(key, num)
        res = df_day[col]
        if res != 0:
            lists = [num, res, col]
            return lists
        else:
            lists = [3, res, col]
            return lists
    ```
    """
    l = day_list.copy()
    l.reverse()
    # print(l)
    for num in l:
        col = "{}_ma_{}".format(key, num)
        res = df_day[col]
        if res != 0:
            lists = [num, res, col]
            return lists
        else:
            lists = [3, res, col]
            return lists

            # 判断方向， 涨趋势或跌趋势 均线是否在价格上方或下方


def key_key_BollSort(df_day, day_list, key="close", method="sort", mode="UP"):
    """
    + df_day, day_list, key="close", method="sort", mode="UP"
    + df_day = df.iloc[day]
    + day_list = wave 波浪
    + key = close, open, low, high 主要信息
    + methord= sort/count def: sort
    + mode = UP/DOWN
    :: return num
    ```python

    a = 0
    counts = 0
    for num in range(len(day_list)):
        MA_col = "{}_ma_{}".format(key, day_list[num])
        col = "{}_ma_{}-{}_Boll".format(key, day_list[num], key)
        if MA_col != 0:
            counts += 1
            if method == "sort":
                if df_day[col] == -1 and mode == "UP":
                    a += 1
                elif df_day[col] == 1 and mode == "DOWN":
                    a -= 1
                else:
                    return a
            elif method == "count":
                a += df_day[col]
    return a / counts
    ```
    """
    a = 0
    counts = 0
    for num in range(len(day_list)):
        MA_col = "{}_ma_{}".format(key, day_list[num])
        col = "{}_ma_{}-{}_Boll".format(key, day_list[num], key)
        if MA_col != 0:
            counts += 1
            if method == "sort":
                if df_day[col] == -1 and mode == "UP":
                    a += 1
                elif df_day[col] == 1 and mode == "DOWN":
                    a -= 1
                else:
                    return a
            elif method == "count":
                a += df_day[col]
    return a / counts


# 判断均线自己涨跌
def key_by_BollSort(df_day, day_list, key="close", method="sort", mode="UP"):
    """
    + df_day, day_list, key="close", method="sort", mode="UP"
    + df_day = df.iloc[day]
    + day_lists = wave 波浪
    + key = close, open, low, high 主要信息
    + methord= sort/count def: sort
    + mode = UP/DOWN def UP 在上面的线，在下面的线
    :: return num
    ```python
    a = 0
    counts = 0
    for num in range(len(day_list)):
        MA_col = "{}_ma_{}".format(key, day_list[num])
        col = "{}_ma_{}_by%_Boll".format(key, day_list[num])
        if MA_col != 0:
            counts += 1
            if method == "sort":
                if df_day[col] == -1 and mode == "UP":
                    a += 1
                elif df_day[col] == 1 and mode == "DOWN":
                    a -= 1
                else:
                    return a
            elif method == "count":
                a += df_day[col]
    return a / counts
    ```
    """
    a = 0
    counts = 0
    for num in range(len(day_list)):
        MA_col = "{}_ma_{}".format(key, day_list[num])
        col = "{}_ma_{}_by%_Boll".format(key, day_list[num])
        if MA_col != 0:
            counts += 1
            if method == "sort":
                if df_day[col] == -1 and mode == "UP":
                    a += 1
                elif df_day[col] == 1 and mode == "DOWN":
                    a -= 1
                else:
                    return a
            elif method == "count":
                a += df_day[col]
    return a / counts


# 判断Main线的高度与两线是否相等 返回 'GR'/'LT'
def Main_Plus(df_day, count_in=1, num=2, mode="UP"):
    """
    Main线相加，是否超过预期值
    + df_day, count_in=1, num=2, mode="UP"
    :: return: True / False
    ```python
    if (
        mode == "UP"
        and df_day["close-open_ma_Main"] + df_day["high-low_ma_Main"] >= count_in / num
        and df_day["close-open_ma_Main"] == df_day["high-low_ma_Main"]
    ):
        return True
    elif (
        mode == "DOWN"
        and df_day["close-open_ma_Main"] + df_day["high-low_ma_Main"] <= count_in / num
        and df_day["close-open_ma_Main"] == df_day["high-low_ma_Main"]
    ):
        return True
    else:
        return False
    ```
    """
    if (
        mode == "UP"
        and df_day["close-open_ma_Main"] + df_day["high-low_ma_Main"] >= count_in / num
        and df_day["close-open_ma_Main"] == df_day["high-low_ma_Main"]
    ):
        return True
    elif (
        mode == "DOWN"
        and df_day["close-open_ma_Main"] + df_day["high-low_ma_Main"] <= count_in / num
        and df_day["close-open_ma_Main"] == df_day["high-low_ma_Main"]
    ):
        return True
    else:
        return False


def Main_compare_or(df_day, count_in=1, num=1.5, mode="UP"):
    """
    比较Main线是否超过预期值
    + df_day, count_in=1, num=1.5, mode="UP"
    ```python
    if mode == "UP" and (
        df_day["close-open_ma_Main"] >= count_in * num
        or df_day["high-low_ma_Main"] >= count_in * num
    ):
        return True
    elif mode == "DOWN" and (
        df_day["close-open_ma_Main"] <= count_in * num
        or df_day["high-low_ma_Main"] <= count_in * num
    ):
        return True
    else:
        return False
    ```
    """
    if mode == "UP" and (
        df_day["close-open_ma_Main"] >= count_in * num
        or df_day["high-low_ma_Main"] >= count_in * num
    ):
        return True
    elif mode == "DOWN" and (
        df_day["close-open_ma_Main"] <= count_in * num
        or df_day["high-low_ma_Main"] <= count_in * num
    ):
        return True
    else:
        return False


def Main_compare_Both(df_day, count_in=1, num=1.5, mode="UP"):
    """
    比较Main线是否超过预期值
    + df_day, count_in=1, num=1.5, mode="UP"
    ```python
    if mode == "UP" and (
        df_day["close-open_ma_Main"] >= count_in * num
        and df_day["high-low_ma_Main"] >= count_in * num
    ):
        return True
    elif mode == "DOWN" and (
        df_day["close-open_ma_Main"] <= count_in * num
        and df_day["high-low_ma_Main"] <= count_in * num
    ):
        return True
    else:
        return False
    ```
    """
    if mode == "UP" and (
        df_day["close-open_ma_Main"] >= count_in * num
        and df_day["high-low_ma_Main"] >= count_in * num
    ):
        return True
    elif mode == "DOWN" and (
        df_day["close-open_ma_Main"] <= count_in * num
        and df_day["high-low_ma_Main"] <= count_in * num
    ):
        return True
    else:
        return False


# 判断SUM金叉死叉


def Sum_cross(df_day, df_day_1):
    """
    # sum线是否产生金叉或者死叉
    + df_day = df.iloc[day]
    + df_day_1 = df.iloc[day - 1]
    ```python
    if (
        int(df_day_1["close_by%_sum"]) <= int(df_day_1["close_by%_sum_12_rolling"])  # G
        and int(df_day_1["close_by%_sum"]) <= int(df_day_1["close_by%_sum_4_rolling"])
    ) and (
        int(df_day["close_by%_sum"]) >= int(df_day["close_by%_sum_12_rolling"])
        and int(df_day["close_by%_sum"]) >= int(df_day["close_by%_sum_4_rolling"])
    ):
        return "G"
    elif (
        int(df_day_1["close_by%_sum"]) >= int(df_day_1["close_by%_sum_12_rolling"])  # X
        and int(df_day_1["close_by%_sum"]) >= int(df_day_1["close_by%_sum_4_rolling"])
    ) and (
        int(df_day["close_by%_sum"]) <= int(df_day["close_by%_sum_12_rolling"])
        and int(df_day["close_by%_sum"]) <= int(df_day["close_by%_sum_4_rolling"])
    ):
        return "X"
    ```
    :: return: G/X
    """
    if (
        int(df_day_1["close_by%_sum"]) <= int(df_day_1["close_by%_sum_12_rolling"])  # G
        and int(df_day_1["close_by%_sum"]) <= int(df_day_1["close_by%_sum_4_rolling"])
    ) and (
        int(df_day["close_by%_sum"]) >= int(df_day["close_by%_sum_12_rolling"])
        and int(df_day["close_by%_sum"]) >= int(df_day["close_by%_sum_4_rolling"])
    ):
        return "G"
    elif (
        int(df_day_1["close_by%_sum"]) >= int(df_day_1["close_by%_sum_12_rolling"])  # X
        and int(df_day_1["close_by%_sum"]) >= int(df_day_1["close_by%_sum_4_rolling"])
    ) and (
        int(df_day["close_by%_sum"]) <= int(df_day["close_by%_sum_12_rolling"])
        and int(df_day["close_by%_sum"]) <= int(df_day["close_by%_sum_4_rolling"])
    ):
        return "X"


def Sum_Rolling(df_day):
    """
    # 比较sam 线中间的顺序关系
    + df_day = df.iloc[day]
    :: retrun: G/X/Gl/Lg
    ```python
    if (
        df_day["close_by%_sum"]  # rolling 'G' sum在最上方
        >= df_day["close_by%_sum_4_rolling"]
        >= df_day["close_by%_sum_12_rolling"]
    ):
        return "G"
    elif (
        df_day["close_by%_sum"]  # rolling 'L' sum在最上方 顺序最下方
        <= df_day["close_by%_sum_4_rolling"]
        <= df_day["close_by%_sum_12_rolling"]
    ):
        return "X"
    elif (
        df_day["close_by%_sum"]  # rolling 'Gl' sum在最上方 但是不顺序
        >= df_day["close_by%_sum_4_rolling"]
        and df_day["close_by%_sum"] >= df_day["close_by%_sum_12_rolling"]
    ):
        return "Gl"
    elif (
        df_day["close_by%_sum"]  # rolling 'Lg' sum在最下方 但是不顺序
        <= df_day["close_by%_sum_4_rolling"]
        and df_day["close_by%_sum"] <= df_day["close_by%_sum_12_rolling"]
    ):
        return "Lg"
    ```

    """
    if (
        df_day["close_by%_sum"]  # rolling 'G' sum在最上方
        >= df_day["close_by%_sum_4_rolling"]
        >= df_day["close_by%_sum_12_rolling"]
    ):
        return "G"
    elif (
        df_day["close_by%_sum"]  # rolling 'L' sum在最上方 顺序最下方
        <= df_day["close_by%_sum_4_rolling"]
        <= df_day["close_by%_sum_12_rolling"]
    ):
        return "X"
    elif (
        df_day["close_by%_sum"]  # rolling 'Gl' sum在最上方 但是不顺序
        >= df_day["close_by%_sum_4_rolling"]
        and df_day["close_by%_sum"] >= df_day["close_by%_sum_12_rolling"]
    ):
        return "Gl"
    elif (
        df_day["close_by%_sum"]  # rolling 'Lg' sum在最下方 但是不顺序
        <= df_day["close_by%_sum_4_rolling"]
        and df_day["close_by%_sum"] <= df_day["close_by%_sum_12_rolling"]
    ):
        return "Lg"


def Sum_inc(df_day, df_day_1):
    """
    # sum线前后日是否变化
    + df_day = df.iloc[day]
    + df_day_1 = df.iloc[day - 1]
    :: return: G/L/E
    ```python
    if df.iloc[day-1]['close_by%_sum'] <df_day['close_by%_sum']:
            return 'G'
    elif df.iloc[day-1]['close_by%_sum'] >df_day['close_by%_sum']:
        return 'L'
    elif df.iloc[day-1]['close_by%_sum'] <=df_day['close_by%_sum']:
        return 'E'
    ```
    """
    if df_day_1["close_by%_sum"] < df_day["close_by%_sum"]:
        return "G"
    elif df_day_1["close_by%_sum"] > df_day["close_by%_sum"]:
        return "L"
    elif df_day_1["close_by%_sum"] == df_day["close_by%_sum"]:
        return "E"


def MA_Boll_by(df_day, key="close", numL=[3, 5, 13, 21], boll=1):

    """
    + df_day = df.iloc[day]
    + MA_Boll_by:
    + df_day, key="close", numL=[3, 5, 13, 21], boll=1
    + 例如： close_ma_by%Boll 两条线是否都为 1 或者 -1
    ```python
    for num in numL:
        col1 = '{}_ma_{}_by%_Boll'.format(key, num)
        if df.iloc[day][col1] != boll: # 1 增长 | -1下跌
            return False
    return True
    ```
    :: return: True False
    """
    for num in numL:
        col = "{}_ma_{}_by%_Boll".format(key, num)
        if df_day[col] != boll:
            return False
    return True


def MA_Key_key_Boll(df_day, key="close", numL=[3, 5, 13, 21], boll=1):
    """
    + 判断例如 close_ma_3-close_Boll 在上在下，使用特定线 1上方 -1下方
    + df_day, key="close", numL=[3, 5, 13, 21], boll=1
    ```python
    for num in numL:
        col2 = '{}_ma_{}-{}_Boll'.format(key, num, key)
        if df.iloc[day][col1] != boll:
            return False
    return True
    ```
    :: return: True False
    """
    for num in numL:
        col = "{}_ma_{}-{}_Boll".format(key, num, key)
        if df_day[col] != boll:
            return False
    return True